/**
 * 
 */
package net.sf.cldsql.dj.mvc;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.security.Principal;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * SjUtl
 */
public class DiContextServletImpl implements DiContext {
    private Map<String,Cookie> cookieMap;
    private HttpServletRequest request;
    private HttpServletResponse response;

    public DiContextServletImpl (HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getParameterMap()
     */
    @SuppressWarnings("unchecked")
    public Map<String, String[]> getParameterMap() {
        return (Map<String, String[]>)request.getParameterMap();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getParam(java.lang.String)
     */
    @Override
    public String getParam(String name) {
        return request.getParameter(name);
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getPathInfo()
     */
    public String getPathInfo() {
        return request.getPathInfo();
    }
    
    private String method;
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getMethod()
     */
    public String getMethod() {
        return method != null ? method : request.getMethod();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#setMethod(java.lang.String)
     */
    public void setMethod(String method) {
        this.method = method;
    }
    
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getSession(boolean)
     */
    @Override
    public DiSession getSession(boolean isNew) {
        HttpSession httpSession = this.request.getSession(isNew);
        DiSession session = httpSession != null? new DiSessionServletImpl(httpSession) : null;
        return session;
    }
    
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#addCookie(java.lang.String, java.lang.String, java.lang.String, java.lang.String, int)
     */
    public void addCookie(String name, String value, String domain, String path, int maxAge){
        Cookie cookie = new Cookie(name,value);
        if (domain != null) {
            cookie.setDomain(domain);
        }
        cookie.setPath(path == null ? "/" : path);
        if(maxAge > 0) {
            cookie.setMaxAge(maxAge);
        }
        this.response.addCookie(cookie);
    }
    
    private Cookie getCookie(String name){
        if (cookieMap == null) {
            cookieMap = readCookieMap();
        }
        if(cookieMap.containsKey(name)){
            Cookie cookie = (Cookie)cookieMap.get(name);
            return cookie;
        }else{
            return null;
        }   
    }
    
    private Map<String,Cookie> readCookieMap(){  
        cookieMap = new HashMap<String,Cookie>();
        Cookie[] cookies = request.getCookies();
        if(null != cookies){
            for(Cookie cookie : cookies){
                cookieMap.put(cookie.getName(), cookie);
            }
        }
        return cookieMap;
    }
    
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getCookieValue(java.lang.String)
     */
    public HashMap<String, Object> getCookieValue(String name) {
        final Cookie cookie = getCookie(name);
        if (cookie != null) {
            return new HashMap<String, Object>() {
                private static final long serialVersionUID = 1L;
            {
                put("name", cookie.getName());
                put("value", cookie.getValue());
                put("domain", cookie.getDomain());
                put("path", cookie.getPath());
                put("maxAge", cookie.getMaxAge());
                put("comment", cookie.getComment());
            }};
        } else {
            return null;
        }
    }
    
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getOutputStream()
     */
    public OutputStream getResponseOutputStream() throws IOException {
        return this.response.getOutputStream();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getWriter()
     */
    public PrintWriter getResponseWriter() throws IOException {
        return this.response.getWriter();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#addResponseHeader(java.lang.String, java.lang.String)
     */
    public void addResponseHeader(String name, String value) {
        this.response.addHeader(name, value);
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#setResponseHeader(java.lang.String, java.lang.String)
     */
    public void setResponseHeader(String name, String value) {
        this.response.setHeader(name, value);
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#setResponseDateHeader(java.lang.String, long)
     */
    public void setResponseDateHeader(String name, long offset) {
        this.response.setDateHeader(name, offset);
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#setResponseCharacterEncoding(java.lang.String)
     */
    public void setResponseCharacterEncoding(String encoding) {
        this.response.setCharacterEncoding(encoding);
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#setResponseContentType(java.lang.String)
     */
    public void setResponseContentType(String contentType) {
        this.response.setContentType(contentType);
    }
    
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getHeader(java.lang.String)
     */
    public String getHeader(String paramString) {
        return this.request.getHeader(paramString);
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getHeaderNames()
     */
    public Enumeration getHeaderNames() {
        return this.request.getHeaderNames();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getHeaders(java.lang.String)
     */
    public Enumeration getHeaders(String paramString) {
        return this.request.getHeaders(paramString);
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getInputStream()
     */
    public InputStream getInputStream() throws IOException {
        return this.request.getInputStream();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getReader()
     */
    public BufferedReader getReader() throws IOException {
        return this.request.getReader();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getCharacterEncoding()
     */
    public String getCharacterEncoding() {
        return this.request.getCharacterEncoding();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getContextPath()
     */
    public String getContextPath() {
        return this.request.getContextPath();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getServletPath()
     */
    public String getServletPath() {
        return this.request.getServletPath();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getAuthType()
     */
    public String getAuthType() {
        return this.request.getAuthType();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getUserPrincipal()
     */
    public Principal getUserPrincipal() {
        return this.request.getUserPrincipal();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getContentType()
     */
    public String getContentType() {
        return this.request.getContentType();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getContentLength()
     */
    public int getContentLength() {
        return this.request.getContentLength();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getProtocol()
     */
    public String getProtocol() {
        return this.request.getProtocol();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getLocalAddr()
     */
    public String getLocalAddr() {
        return this.request.getLocalAddr();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getLocalPort()
     */
    public int getLocalPort() {
        return this.request.getLocalPort();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getLocalName()
     */
    public String getLocalName() {
        return this.request.getLocalName();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getPathTranslated()
     */
    public String getPathTranslated() {
        return this.request.getPathTranslated();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getQueryString()
     */
    public String getQueryString() {
        return this.request.getQueryString();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getRemoteAddr()
     */
    public String getRemoteAddr() {
        return this.request.getRemoteAddr();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getRemoteHost()
     */
    public String getRemoteHost() {
        return this.request.getRemoteHost();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getRemotePort()
     */
    public int getRemotePort() {
        return this.request.getRemotePort();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getRemoteUser()
     */
    public String getRemoteUser() {
        return this.request.getRemoteUser();
    }
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiContext#getRequestedSessionId()
     */
    public String getRequestedSessionId() {
        return this.request.getRequestedSessionId();
    }
    
}
